#include "gtkdock.h"



GdkPixmap* create_pixmap(GtkWidget *widget, const gchar *filename)
{
  GdkColormap *colormap;
  GdkPixmap *gdkpixmap;
  
  colormap = gtk_widget_get_colormap (widget);
  gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL, NULL, filename);
  if (gdkpixmap == NULL)
    {
      g_warning ("Error loading pixmap file: %s", filename);
      return NULL;
    }

  return gdkpixmap;
}

void send_msg(GAmsnApplet * dock, char *command)
{
	//printf("%d", sizeof command);
	if(!(fputs(command, dock->stream))) {
		fclose(dock->stream);
		g_error("Error sending packet to AMSN!");
		applet_widget_remove(APPLET_WIDGET(dock->applet));
	//	gtk_main_quit();
	}// else {
	//	printf("Sent message %s", command);
	//}
}

void redisplay_pic(GAmsnApplet * dock)
{
	switch(dock->status)
	{
		case ST_ONLINE:
			dock->picbuffer = gtk_pixmap_new(dock->online_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_OFFLINE:
			dock->picbuffer = gtk_pixmap_new(dock->offline_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_NOACT:
			dock->picbuffer = gtk_pixmap_new(dock->noact_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_BUSY:
			dock->picbuffer = gtk_pixmap_new(dock->busy_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_BRB:
			dock->picbuffer = gtk_pixmap_new(dock->brb_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_AWAY:
			dock->picbuffer = gtk_pixmap_new(dock->away_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_ONPHONE:
			dock->picbuffer = gtk_pixmap_new(dock->phone_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_LUNCH:
			dock->picbuffer = gtk_pixmap_new(dock->lunch_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
		case ST_APP_OFFLINE:
			dock->picbuffer = gtk_pixmap_new(dock->appear_pic, NULL);
			gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );
			break;
	}

	gtk_widget_show_all( GTK_WIDGET( dock->applet ) );
}

void change_status(GAmsnApplet * dock, gint newstatus)
{
	if(dock->status != newstatus)
	{
		gtk_container_remove( GTK_CONTAINER( dock->frame ), dock->picbuffer );
		dock->status = newstatus;
	//	printf("New Status is : %d \n", dock->status);
		redisplay_pic( dock );
	}
}

static void open_amsn(GtkWidget *appwid, GdkEventButton * event, GAmsnApplet *dock)
{
	send_msg(dock, "GO_OPEN\n");
}

static void open_inbox(AppletWidget *appwid, GAmsnApplet *dock)
{
        if(dock->status != ST_OFFLINE)
		send_msg(dock, "OPEN_INBOX\n");
}

static void signin(AppletWidget *appwid, GAmsnApplet *dock)
{
        if(dock->status == ST_OFFLINE) 
		send_msg(dock, "SIGNIN\n");
}

static void signin_as(AppletWidget *appwid, GAmsnApplet *dock)
{
	if(dock->status == ST_OFFLINE)
	        send_msg(dock, "SIGNINAS\n");
}

static void signout(AppletWidget *appwid, GAmsnApplet *dock)
{
        if(dock->status != ST_OFFLINE)
		send_msg(dock, "SIGNOUT\n");
}

static void go_online(AppletWidget * appwid, GAmsnApplet *dock)
{
        if((dock->status != ST_OFFLINE) && (dock->status != ST_ONLINE))
		send_msg(dock, "GO_ONLINE\n");
}

static void go_noact(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_NOACT))
		send_msg(dock, "GO_NOACT\n");
}

static void go_busy(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_BUSY))
		send_msg(dock, "GO_BUSY\n");
}

static void go_brb(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_BRB))
		send_msg(dock, "GO_BRB\n");
}

static void go_away(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_AWAY))
		send_msg(dock, "GO_AWAY\n");
}

static void go_phone(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_ONPHONE))
		send_msg(dock, "GO_ONPHONE\n");
}

static void go_lunch(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_LUNCH))
		send_msg(dock, "GO_LUNCH\n");
}

static void go_appear(AppletWidget * appwid, GAmsnApplet *dock)
{
	if((dock->status != ST_OFFLINE) && (dock->status != ST_APP_OFFLINE))
		send_msg(dock, "GO_APP_OFFLINE\n");
}

static void close_dock(AppletWidget * appwid, GAmsnApplet *dock)
{
	//g_print(_("Sending Close!"));
	send_msg(dock, "SESSION_END\n");
	fclose(dock->stream);
	applet_widget_remove(APPLET_WIDGET (dock->applet));
	applet_widget_gtk_main_quit();
}

static void exit_amsn(AppletWidget * appwid, GAmsnApplet *dock)
{
	send_msg(dock, "AMSN_CLOSE\n");
}

static void proc_data(GAmsnApplet *dock, gint c, GdkInputCondition condition)
{
	char buffer[250];

//	g_print("Pre Read\n");
       	fgets(buffer, sizeof buffer, dock->stream);
//	printf("Received message : %s", buffer);
        if (!strncmp(buffer, "SESSION_END", 11)) {
        	fclose(dock->stream);
//		g_print(_("Got close"));
		applet_widget_remove(APPLET_WIDGET (dock->applet));
		applet_widget_gtk_main_quit();
	} else {

//	printf("Processing data : %s", buffer);
	
	if (!strncmp(buffer, "NLN", 3)) {
		change_status(dock, ST_ONLINE);
	}
	else if (!strncmp(buffer, "IDL", 3)) {
		change_status(dock, ST_NOACT);
	}
	else if (!strncmp(buffer, "BSY", 3)) {
		change_status(dock, ST_BUSY);
	}
	else if (!strncmp(buffer, "BRB", 3)) {
		change_status(dock, ST_BRB);
	}
	else if (!strncmp(buffer, "AWY", 3)) {
		change_status(dock, ST_AWAY);
	}
	else if (!strncmp(buffer, "PHN", 3)) {
		change_status(dock, ST_ONPHONE);
	}
	else if (!strncmp(buffer, "LUN", 3)) {
		change_status(dock, ST_LUNCH);
	}
	else if (!strncmp(buffer, "HDN", 3)) {
		change_status(dock, ST_APP_OFFLINE);
	}
	else if (!strncmp(buffer, "FLN", 3)) {
		change_status(dock, ST_OFFLINE);
	}
	else {
		g_print(_("got unknown dock response, closing dock!"));
		close_dock(dock->status, dock);
	}
	}
}

void init_session(void* arg) {
	char *srvr_addr = "127.0.0.1";
        char *srvr_port = "11983";
        char buffer[250];
        int z;
        struct sockaddr_in adr_srvr;
        int len_inet;
	int s = -1;
	int c = -1;

	
	GAmsnApplet *dock = (GAmsnApplet *)arg;
        
        s = socket(PF_INET, SOCK_STREAM, 0);
        
        memset(&adr_srvr, 0, sizeof adr_srvr);
        adr_srvr.sin_family = AF_INET;
        adr_srvr.sin_port = htons(atoi(srvr_port));
        adr_srvr.sin_addr.s_addr = inet_addr(srvr_addr);

        len_inet = sizeof adr_srvr;
        
	c = connect(s, (struct sockaddr *)&adr_srvr, len_inet);
	if ( c == -1 ) {
		close(s);
		g_error("Problem connecting to server!\n");
	}

	dock->stream = fdopen(s, "r+");
	if(!dock->stream) {
		close(s);
		g_error("Problem creating a file stream!\n");
	}
	
	setlinebuf(dock->stream);
	
//	printf("Suppose to get hand now!");
	fgets(buffer, sizeof buffer, dock->stream);
	if (!strncmp(buffer, "SESSION_HAND", 12)) {
//		g_print("Got message SESSION_HAND");
		
		fputs("SESSION_HAND\n", dock->stream);

//		g_print("Wrote SESSION_HAND");
		
		gdk_input_add_full(s, GDK_INPUT_READ, GTK_SIGNAL_FUNC(proc_data), dock, NULL);

	} else {
		fclose(dock->stream);
		g_error("Failed to initialize session with AMSN!\n");
	}
}

void init_dock(GAmsnApplet * dock)
{
	GdkColor bg_color;
	char *tpath;

	stpcpy(tpath, dock->path);
	
	dock->applet = applet_widget_new("amsndock");
	if (!dock->applet)
		g_error("Can't create applet!\n");

	gtk_signal_connect (GTK_OBJECT (dock->applet), "destroy", GTK_SIGNAL_FUNC (close_dock), dock);
	
	dock->online_pic = create_pixmap(dock->applet, strncat(dock->path, "online.xpm", 10));
	stpcpy(dock->path, tpath);
	dock->offline_pic = create_pixmap(dock->applet, strncat(dock->path, "offline.xpm", 11));
	stpcpy(dock->path, tpath);
	dock->busy_pic = create_pixmap(dock->applet, strncat(dock->path, "busy.xpm", 8));
	stpcpy(dock->path, tpath);
	dock->away_pic = create_pixmap(dock->applet, strncat(dock->path, "away.xpm", 8));
	stpcpy(dock->path, tpath);
	dock->lunch_pic = create_pixmap(dock->applet, strncat(dock->path, "lunch.xpm", 9));
	stpcpy(dock->path, tpath);
	dock->brb_pic = create_pixmap(dock->applet, strncat(dock->path, "brb.xpm", 7));
	stpcpy(dock->path, tpath);
	dock->appear_pic = create_pixmap(dock->applet, strncat(dock->path,  "appear.xpm", 10));
	stpcpy(dock->path, tpath);
	dock->noact_pic = create_pixmap(dock->applet, strncat(dock->path, "noact.xpm", 9));
	stpcpy(dock->path, tpath);
	dock->phone_pic = create_pixmap(dock->applet, strncat(dock->path, "onphone.xpm", 11));

	
	dock->eventbox = gtk_event_box_new();

	gtk_widget_set_events(dock->eventbox, GDK_BUTTON_PRESS_MASK);
	gtk_signal_connect(GTK_OBJECT(dock->eventbox), "button_press_event", GTK_SIGNAL_FUNC(open_amsn), dock);
	
	dock->frame = gtk_frame_new ( NULL );
	gtk_frame_set_shadow_type( GTK_FRAME( dock->frame ), GTK_SHADOW_IN );

	dock->status = ST_OFFLINE;
	
	gtk_widget_set_usize(dock->frame, 48, 48);

	dock->picbuffer = gtk_pixmap_new(dock->offline_pic, NULL);

	gtk_container_add( GTK_CONTAINER( dock->frame ), dock->picbuffer );

	gtk_container_add( GTK_CONTAINER( dock->eventbox), dock->frame);
	
	applet_widget_add( APPLET_WIDGET( dock->applet ), dock->eventbox );
		
	gtk_widget_show_all( GTK_WIDGET( dock->applet ) );
	
	applet_widget_register_stock_callback(APPLET_WIDGET (dock->applet), "inbox", GNOME_STOCK_MENU_MAIL, _("My Hotmail In-Box"), GTK_SIGNAL_FUNC(open_inbox), dock);
	applet_widget_register_callback_dir(APPLET_WIDGET (dock->applet), "status", _("My Status"));
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/online", _("Online"), GTK_SIGNAL_FUNC(go_online), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/no_activity", _("No Activity"), GTK_SIGNAL_FUNC(go_noact), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/busy", _("Busy"), GTK_SIGNAL_FUNC(go_busy), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/brb", _("Be Right Back"), GTK_SIGNAL_FUNC(go_brb), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/away", _("Away"), GTK_SIGNAL_FUNC(go_away), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/phone", _("On The Phone"), GTK_SIGNAL_FUNC(go_phone), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/lunch", _("Gone to Lunch"), GTK_SIGNAL_FUNC(go_lunch), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "status/app_offline", _("Appear Offline"), GTK_SIGNAL_FUNC(go_appear), dock);
	applet_widget_register_stock_callback(APPLET_WIDGET (dock->applet), "signin", GNOME_STOCK_PIXMAP_PROPERTIES, _("Sign-In"), GTK_SIGNAL_FUNC(signin), dock);
	applet_widget_register_stock_callback(APPLET_WIDGET (dock->applet), "signinas", GNOME_STOCK_PIXMAP_PREFERENCES, _("Sign-In As.."), GTK_SIGNAL_FUNC(signin_as), dock);
	applet_widget_register_stock_callback(APPLET_WIDGET (dock->applet), "signout", GNOME_STOCK_PIXMAP_EXIT, _("Sign-Out"), GTK_SIGNAL_FUNC(signout), dock);
	applet_widget_register_callback(APPLET_WIDGET (dock->applet), "exit", _("Exit amsn"), GTK_SIGNAL_FUNC(exit_amsn), dock);
		
}


int main(int argc, char **argv)
{
	GAmsnApplet dock;
	
	applet_widget_init( "AMSN DOCK", "1.0", argc, argv, NULL, 0, NULL );
		
	if( argc != 2 ) {
		g_print(_("Wrong number of arguments, run the dock from AMSN menu!\n"));
	} else {
		stpcpy(dock.path, argv[1]);
		
		init_dock(&dock);
	
		init_session(&dock);	
     
		applet_widget_gtk_main();

		return 0;
	}
}
